package org.folio.rest.impl.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import org.folio.cql2pgjson.exception.FieldException;
import org.folio.rest.impl.other.PartyUtil;
import org.folio.rest.impl.other.reserve_station.ReserveEndPond;
import org.folio.rest.impl.other.reserve_station.ReserveQueueService;
import org.folio.rest.impl.util.DBName;
import org.folio.rest.jaxrs.model.*;
import org.folio.rest.persist.PostgresClient;
import org.folio.rest.persist.cql.CQLWrapper;
import org.folio.rest.tools.utils.BinaryOutStream;
import org.folio.rest.tools.utils.ValidationHelper;

import javax.ws.rs.core.Response;
import java.util.List;
import java.util.Optional;

import static io.vertx.core.Future.factory;
import static io.vertx.core.Future.succeededFuture;

/**
 * @author lee
 * @Classname WebInfoDetailService
 * @Description TODO
 * @Date 2020/7/7 10:54
 * @Created by lee
 */
public class WebInfoDetailService {


    public static void partyWebInfoDetail(String id, String barcode, PostgresClient pg, Handler<AsyncResult<PartyWebDetailsInfo>> asyncResultHandler) {
        PartyWebDetailsInfo partyWebDetailsInfo = new PartyWebDetailsInfo();

        pg.getById("party", id, Party.class, reply -> {
            if (reply.succeeded()) {
                Party party = reply.result();

                CQLWrapper cql = null;
                try {
                    cql = PartyUtil.getCQL("( isDel = 0 and partyId = \"" + party.getId() + "\")", -1, -1, "reserve");
                } catch (FieldException e) {
                    e.printStackTrace();
                }

                pg.get("reserve", org.folio.rest.jaxrs.model.ReserveGroup.class,
                        new String[]{"*"}, cql, true, false, replyReserve -> {
                            if (replyReserve.succeeded()) {

                                List<ReserveGroup> reserveGroup = replyReserve.result().getResults();
                                Integer totalRecords = replyReserve.result().getResultInfo().getTotalRecords();
                                Integer readerReserve = 0 ;
                                if (!StrUtil.isBlankOrUndefined(barcode)){
                                  readerReserve = Math.toIntExact(reserveGroup.stream().filter(a -> a.getReaderReserveGroup().size() > 0 && barcode.equals(a.getReaderReserveGroup().get(0).getBarcode())).count());
                                }

                                ReserveQueueService serve = ReserveEndPond.getReserveQueueService(id);
                                if (serve != null && barcode !=null && !StrUtil.isEmptyOrUndefined(barcode)){
                                    WebReserveStatus result = serve.readerReserveStatus(barcode);
                                    partyWebDetailsInfo.setWebReserveStatus(result);
                                }else{
                                    WebReserveStatus result = new WebReserveStatus();
                                    result.setRemaining(0);
                                    result.setIsReserve(false);
                                    partyWebDetailsInfo.setWebReserveStatus(result);
                                }
                                partyWebDetailsInfo.setParty(party);
                                partyWebDetailsInfo.setReserveAmount(totalRecords);
                                partyWebDetailsInfo.setReaderIsReserve("0".equals(readerReserve.toString()) ? false : true);
                                partyWebDetailsInfo.setCreateDate(DateUtil.now());
                                PunishmentRecord temp = new PunishmentRecord();
                                temp.setStatus("0");
                                partyWebDetailsInfo.setPunishmentRecord(temp);
                                if (!StrUtil.isEmptyOrUndefined(barcode)){
                                    CQLWrapper cqlWrapper = PartyUtil.CQLCreate("(readerInfo.barcode == \""+barcode+"\")",-1,-1, DBName.NOTIFY_TABLE_READER_CREDIT);
                                    pg.get(DBName.NOTIFY_TABLE_READER_CREDIT,ReaderCreditRecord.class,cqlWrapper,true,false,getReply->{
                                        if (getReply.succeeded()){
                                            Optional<ReaderCreditRecord> readerRecord = getReply.result().getResults().stream().filter(a -> a.getReaderInfo().getBarcode().equals(barcode)).findAny();
                                            if (readerRecord.isPresent()){
                                                ReaderCreditRecord readerCreditRecord = readerRecord.get();
                                                Optional<PunishmentRecordGroup> punishment = readerCreditRecord.getPunishmentRecordGroup().stream().filter(a -> a.getStatus().equals("1")).findAny();
                                                if (punishment.isPresent()){
                                                    PunishmentRecordGroup source = punishment.get();
                                                    PunishmentRecord punishmentRecord = new PunishmentRecord();
                                                    BeanUtil.copyProperties(source,punishmentRecord);
                                                    partyWebDetailsInfo.setPunishmentRecord(punishmentRecord);
                                                }
                                            }
                                        }
                                        asyncResultHandler.handle(Future.succeededFuture(partyWebDetailsInfo));
                                    }
                                );
                                }else{
                                    asyncResultHandler.handle(Future.succeededFuture(partyWebDetailsInfo));
                                }

                            }else{

                                asyncResultHandler.handle(Future.failedFuture(replyReserve.cause()));
                            }
                        });
            }else {
                asyncResultHandler.handle(Future.failedFuture(reply.cause()));
            }
        });

    }
}
